package wsepForum.domain.handlers;

import java.awt.image.BufferedImage;
import java.util.Collection;
import java.util.Date;
import java.util.Vector;

import wsepForum.common.elements.*;
import wsepForum.common.elements.User.UserType;
import wsepForum.domain.Session;
import wsepForum.domain.exceptions.NoSuchUserSessionExcepion;
import wsepForum.domain.exceptions.SystemFailureException;
import wsepForum.domain.exceptions.UnAuthorizedException;
import wsepForum.domain.exceptions.WrongPasswordException;
import wsepForum.logging.ForumLogger;
import wsepForum.persistance.IPersistentHandler;
import wsepForum.persistance.exceptions.DataBaseIOException;
import wsepForum.persistance.exceptions.WrongElementIDException;
import wsepForum.persistance.exceptions.WrongUserNameException;

/**
 * The main interface between the GUI layer and the domain layer.
 * Provides the transportation of information between the GUI and the persistent.
 * Each further inheritance implements/overrides the services a certain user group
 * can receive from the system.
 *
 * This handler deals with a guest user(not logged-in user)
 *
 * @author Amir Harel & Ariel Rozen & Oren Ben-Haim
 *
 */
public class GuestHandler extends AUserHandler {

	/*****************************
	 * CONSTRUCTOR               *
	 *****************************/
	/**
	 * @param persistent The interface supplied by the persistent layer.
	 */
	public GuestHandler(IPersistentHandler persistent) {
		super(persistent);
	}

	/*****************************
	 * METHODS                   *
	 *****************************/

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#deleteMessageAuthentication(wsepForum.common.elements.Message, int)
	 */
	@Override
	public boolean deleteMessageAuthentication(Message messageToDelete,int sectionID) throws SystemFailureException {
		return false;
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#editMessageAuthentication(wsepForum.common.elements.Message, int)
	 */
	@Override
	public boolean editMessageAuthentication(Message messageToEdit,int sectionID) throws SystemFailureException{
		return false;
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#editSectionAuthentication()
	 */
	@Override
	public boolean editSectionAuthentication() {
		return false;
	}
	
	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#addMessageToTopic(double, java.lang.String, java.lang.String)
	 */
	@Override
	public Topic addMessageToTopic(int topicID, String messageHeadline, String messageBody) throws Exception {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#createSection(int, java.lang.String, java.util.Collection)
	 */
	@Override
	public Section createSection(int parentSectionID, String sectionName, Collection<String> moderators) throws Exception {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#addModeratorToSection(int, java.lang.String)
	 */
	@Override
	public Section addModeratorToSection(int sectionID, String userName) throws UnAuthorizedException, WrongElementIDException,
						WrongUserNameException, SystemFailureException {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#removeModerator(int, java.lang.String)
	 */
	@Override
	public Section removeModerator(int SectionID, String userName) throws UnAuthorizedException, WrongUserNameException,
						WrongElementIDException, SystemFailureException {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#removeSection(int)
	 */
	@Override
	public Section removeSection(int sectionID) throws Exception {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#createTopic(double, java.lang.String, java.lang.String)
	 */
	@Override
	public Topic createTopic(int sectionID, String messageHeadline, String messageBody) throws Exception {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#editMessage(double, double, java.lang.String, java.lang.String)
	 */
	@Override
	public Topic editMessage(int topicID, int messageToEditID, String messageHeadLine, String messageBody) throws Exception {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#deleteMessage(int)
	 */
	@Override
	public AForumElement deleteMessage(int parentTopicID, int messageToDeleteID) throws Exception{
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#login(java.lang.String, java.lang.String)
	 */
	@Override
	public AUserHandler login(String userName, String password)
				throws WrongUserNameException,UnAuthorizedException,WrongPasswordException, DataBaseIOException {

		AUserHandler resHandler = this;
		if (this.getPersistent().login(userName,password)) {
			User user = this.getPersistent().getUser(userName);
			switch(user.getUserType()) {
				case MEMBER:
					resHandler = new MemberHandler(user,this.getPersistent());
					ForumLogger.getInstance().info(userName + " logged in as Member", ForumLogger.LoggerCategory.DOMAIN);
					break;
				case MODERATOR:
					resHandler = new ModeratorHandler(user,this.getPersistent());
					ForumLogger.getInstance().info(userName + " logged in as Moderator", ForumLogger.LoggerCategory.DOMAIN);
					break;
				case ADMIN:
					resHandler = new AdminHandler(user,this.getPersistent());
					ForumLogger.getInstance().info(userName + " logged in as Admin", ForumLogger.LoggerCategory.DOMAIN);
					break;
			}
		}	
		// Login failure
		else {
			throw new WrongPasswordException();
		}
		return resHandler;
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#logout()
	 */
	@Override
	public AUserHandler logout(Session session) throws UnAuthorizedException, NoSuchUserSessionExcepion, SystemFailureException {
		throw new UnAuthorizedException();
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#register(java.lang.String, java.lang.String)
	 */
	@Override
	public synchronized boolean register(String userName, String password) throws UnAuthorizedException, SystemFailureException {
		for (int i = 0; i < 5; i++) {
			try {
				// check if the user name exist in the DB.
				boolean usernameTaken = true;
				try {
					this.getPersistent().getUser(userName);
				} catch (WrongUserNameException e) {
					ForumLogger.getInstance().info("trying to register with userName " + userName + " which is alredy taken", ForumLogger.LoggerCategory.DOMAIN);
					usernameTaken = false;
				}
	
				if ((userName.equalsIgnoreCase("guest")) || usernameTaken){
	
					ForumLogger.getInstance().info("fail to register with userName " + userName, ForumLogger.LoggerCategory.DOMAIN);
	
					return false;
				}
				else {
					User user = new User(userName,password,UserType.MEMBER);
					this.getPersistent().setUser(user);
	
					ForumLogger.getInstance().info("user " + userName + "has register to the system", ForumLogger.LoggerCategory.DOMAIN);
	
					return true;
	
				}
			} catch (DataBaseIOException e) {
				continue;
			}
		}
		throw new SystemFailureException("can't register at the moment - system failure");
	}

	/* (non-Javadoc)
	 * @see wsepForum.domain.handlers.AUserHandler#removeUser(java.lang.String)
	 */
	@Override
	public boolean removeUser(String userName) throws Exception {
		throw new UnAuthorizedException();
	}
	
	@Override
	public boolean changePassword(String oldPass, String newPass) throws Exception {
		throw new UnAuthorizedException();
	}

	@Override
	public BufferedImage makeMessageCountStatistics(Date date) throws UnAuthorizedException {
		throw new UnAuthorizedException();
	}

	@Override
	public BufferedImage makeUserCountStatistics(Date date) throws UnAuthorizedException {
		throw new UnAuthorizedException();
	}

	@Override
	public BufferedImage makeUserMessagePerDay(Date fromDate, String user) throws UnAuthorizedException {
		throw new UnAuthorizedException();
	}

	@Override
	public Vector<String> getManagedUsernames() {
		return new Vector<String>();
	}



}
